package com.wxapp.admin.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wxapp.admin.api.pojo.entity.CompanyDO;
import com.wxapp.admin.api.pojo.entity.CompanyPictureDO;
import com.wxapp.admin.api.pojo.entity.UserCompanyDO;
import com.wxapp.admin.api.pojo.vm.company.PCompanyDetailVm;
import com.wxapp.admin.api.pojo.vm.company.PCompanyPageVm;
import com.wxapp.admin.api.pojo.vo.company.QCompanyAddPictureVo;
import com.wxapp.admin.api.pojo.vo.company.QCompanyPageVo;
import com.wxapp.admin.api.pojo.vo.company.QCompanySaveVo;
import com.wxapp.admin.api.pojo.vo.company.QCompanyUpdateVo;
import com.wxapp.admin.service.mapper.CompanyMapper;
import com.wxapp.admin.service.mapper.CompanyPictureMapper;
import com.wxapp.admin.service.mapper.UserCompanyMapper;
import com.wxapp.admin.service.service.CompanyService;
import com.wxapp.common.constant.base.IBaseService;
import com.wxapp.common.constant.pojo.vm.ResultVm;
import com.wxapp.common.constant.pojo.vo.UserVo;
import com.wxapp.common.util.check.CheckUtil;
import com.wxapp.common.util.condition.ConditionUtil;
import com.wxapp.common.util.copy.CopyUtil;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author lgl
 * @Description 公司管理
 * @Datetime 2022/6/2 15:08
 * @Modified By
 */
@Service
@RequiredArgsConstructor
public class CompanyServiceImpl extends IBaseService implements CompanyService {
    private final CompanyMapper companyMapper;
    private final UserCompanyMapper userCompanyMapper;
    private final CompanyPictureMapper companyPictureMapper;

    @Override
    public ResultVm<PCompanyDetailVm> detailCompany(UserVo user, String id) {
        CompanyDO companyDO;
        if (CheckUtil.isNullString(id)) {
            LambdaQueryWrapper<UserCompanyDO> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CheckUtil.isNullString(id), UserCompanyDO::getUserId, user.getId());
            wrapper.eq(CheckUtil.isNotNullString(id), UserCompanyDO::getId, id);
            wrapper.eq(UserCompanyDO::getStatus, true);
            UserCompanyDO wxappCompanyDO = userCompanyMapper.selectFirst(wrapper);
            LambdaQueryWrapper<CompanyDO> companyWrapper = new LambdaQueryWrapper<>();
            companyWrapper.eq(CompanyDO::getId, wxappCompanyDO.getCompanyId()).eq(CompanyDO::getStatus, true);
            companyDO = companyMapper.selectFirst(companyWrapper);
        } else {
            companyDO = companyMapper.selectById(id);
        }

        if (CheckUtil.isNullObject(companyDO)) {
            return success();
        }
        var pGetMyCompanyVo = CopyUtil.copyObjectNew(companyDO, PCompanyDetailVm::new, null);
        LambdaQueryWrapper<CompanyPictureDO> picture = new LambdaQueryWrapper<>();
        picture.eq(pGetMyCompanyVo.getId() != null, CompanyPictureDO::getCompanyId, pGetMyCompanyVo.getId());
        var wxappCompanyPictureDOS = companyPictureMapper.selectList(picture);
        pGetMyCompanyVo.setUrl(wxappCompanyPictureDOS.stream().map(CompanyPictureDO::getUrl).collect(Collectors.toList()));
        return success(pGetMyCompanyVo);
    }

    @Override
    public ResultVm<Page<PCompanyPageVm>> pageCompany(QCompanyPageVo qCompanyPageVo) {
        Map<SFunction<CompanyDO, ?>, SqlKeyword> conditions = new HashMap<>();
        conditions.put(CompanyDO::getName, SqlKeyword.LIKE);
        conditions.put(CompanyDO::getName, SqlKeyword.LIKE);
        var condition = ConditionUtil.getSCondition(CompanyDO::new, qCompanyPageVo, PCompanyPageVm.class, conditions,null);
        condition.ge(CheckUtil.isNotNullObject(qCompanyPageVo.getStartTime()), CompanyDO::getCreateTime, qCompanyPageVo.getStartTime());
        condition.le(CheckUtil.isNotNullObject(qCompanyPageVo.getEndTime()), CompanyDO::getCreateTime, qCompanyPageVo.getEndTime());
        var page = ConditionUtil.getPage(qCompanyPageVo, CompanyDO.class);
        Page selectPage = companyMapper.selectPage(page, condition);
        return success(CopyUtil.copyPage(selectPage, PCompanyPageVm::new, null));
    }

    @Override
    public ResultVm<String> saveCompany(UserVo userVo, QCompanySaveVo qCompanySaveVo) {
        var userId = userVo.getId();
        LambdaQueryWrapper<CompanyDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CompanyDO::getName, qCompanySaveVo.getName()).eq(CompanyDO::getStatus, true);
        var count = companyMapper.selectCount(wrapper);
        if (count > 0) {
            return error("已经存在该名称的公司");
        }
        var companyDO = CopyUtil.copyObjectNew(qCompanySaveVo, CompanyDO::new, (s, r) -> {
            r.setCreateBy(userId);
            return null;
        });
        companyMapper.insert(companyDO);
        var urls = qCompanySaveVo.getUrl();
        if (CheckUtil.isNotNullList(urls)) {
            List<CompanyPictureDO> companyPicture = new ArrayList<>();
            var companyId = companyDO.getId();
            urls.forEach(s -> {
                CompanyPictureDO companyP = new CompanyPictureDO();
                companyP.setCompanyId(companyId);
                companyP.setUrl(s);
                companyP.setCreateBy(userId);
                companyPicture.add(companyP);
            });
            if (CheckUtil.isNotNullList(companyPicture)) {
                companyPictureMapper.insertBatch(companyPicture);
            }
        }
        return success();
    }

    @Override
    public ResultVm<String> updateCompany(UserVo userVo, QCompanyUpdateVo qSaveVo) {
        if (qSaveVo.getDefaulted()){
            var query=new LambdaQueryWrapper<CompanyDO>();
            query.eq(CompanyDO::getStatus,true)
                    .ne(CompanyDO::getId,qSaveVo.getId())
                    .eq(CompanyDO::getDefaulted,false);
            boolean exist = companyMapper.isExist(query);
            if (exist){
                return error("已经存在客户端默认公司");
            }
        }

        var companyDO = companyMapper.selectById(qSaveVo.getId());
        var userId = userVo.getId();
        if (CheckUtil.isNullObject(companyDO)) {
            return error("没有找到公司信息");
        }
        CopyUtil.copyObject(qSaveVo, companyDO, (s, r) -> {
            r.setUpdateBy(userId);
            return null;
        });
        companyMapper.updateById(companyDO);
        return success();
    }

    @Override
    @GlobalTransactional(rollbackFor = {Exception.class, RuntimeException.class})
    public ResultVm<String> deleteCompany(UserVo userVo, String id) {
        var companyDO = companyMapper.selectById(id);
        var userId = userVo.getId();
        if (CheckUtil.isNullObject(companyDO)) {
            return error("没有找到公司信息");
        }
        companyDO.setUpdateBy(userId);
        companyDO.setStatus(false);
        companyMapper.updateById(companyDO);
        LambdaQueryWrapper<CompanyPictureDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CompanyPictureDO::getCompanyId, id).eq(CompanyPictureDO::getStatus, true);
        var pictureS = companyPictureMapper.selectList(wrapper);
        if (CheckUtil.isNotNullList(pictureS)) {
            pictureS.stream().forEach(s -> {
                s.setStatus(false);
                s.setUpdateBy(userId);
            });
            companyPictureMapper.batchSaveOrUpdate(pictureS);
        }
        return success();
    }

    @Override
    @GlobalTransactional(rollbackFor = {Exception.class, RuntimeException.class})
    public ResultVm<String> addPicture(UserVo userVo, QCompanyAddPictureVo qCompanyAddPictureVo) {
        LambdaQueryWrapper<CompanyPictureDO> query = new LambdaQueryWrapper<>();
        query.eq(CompanyPictureDO::getStatus, true).eq(CompanyPictureDO::getCompanyId, qCompanyAddPictureVo.getId());
        var companyPictureDO = companyPictureMapper.selectList(query);
        if (CheckUtil.isNotNullList(companyPictureDO)) {
            companyPictureDO.forEach(s -> s.setStatus(false));
            companyPictureMapper.batchSaveOrUpdate(companyPictureDO);
        }
        List<CompanyPictureDO> pictureDOS = new ArrayList<>();
        qCompanyAddPictureVo.getUrl().forEach(s -> {
            CompanyPictureDO pictureDO = new CompanyPictureDO();
            pictureDO.setCompanyId(qCompanyAddPictureVo.getId());
            pictureDO.setUrl(s);
            pictureDO.setStatus(true);
            pictureDO.setCreateBy(userVo.getId());
            pictureDOS.add(pictureDO);
        });
        if (CheckUtil.isNotNullList(pictureDOS)) {
            companyPictureMapper.insertBatch(pictureDOS);
        }
        return success();
    }

    @Override
    public ResultVm<List<String>> getPicture(String companyId) {
        LambdaQueryWrapper<CompanyPictureDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CompanyPictureDO::getStatus, true).eq(CompanyPictureDO::getCompanyId, companyId);
        var companyPictureDOS = companyPictureMapper.selectList(wrapper);
        var collect = companyPictureDOS.stream().map(CompanyPictureDO::getUrl).toList();
        return success(collect);
    }

    @Override
    public ResultVm<List<String>> getPictureByUser(UserVo userVo) {
        return success(companyPictureMapper.getPictureByUser(userVo));
    }
}
